/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bgate.object;

import com.bgate.core.Debug;
import com.bgate.screen.GameScreen;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.Sprite;

/**
 *
 * @author ChrisMorian
 */
public abstract class Character extends Sprite {
//==========================

    public int dx, dy;
    public int backX, backY/*180*/;
    //=================== Type Character
    //========================== state ==========================
    public boolean autoControl;
    public static final int IDLE = 0;
    public static final int BACKWARD = 1;
    public static final int FORWARD = 2;
    public static final int SIT = 3;
    public static final int JUM = 4;
    public static final int RUN = 5;
    public static final int JUMP_BACK = 6;
    public static final int JUMP_FORWARD = 7;
    public static final int KICK = 9;
    public static final int KICK_DOWN = 10;
    public static final int PUNCH = 13;
    public static final int REPEATED_PUNCH = 14;
    public static final int PUNCH_DOWN = 15;
    public static final int WRESTLE = 17;
    public static final int JUMP_FORWARD_FIGHT = 18;
    public static final int JUMP_BACKWARD_FIGHT = 19;
    public static final int JUMP_FIGHT = 20;
    public static final int JUMP_SKILL1 = 21;
    public static final int SKILL1 = 22;
    public static final int SKILL2 = 23;
    public static final int BEPUNCH = 25;
    public static final int BEFALL1 = 26;
    public static final int BEWRESTLE = 27;
    public static final int NEARFIGHT = 28;
    public static final int HIGH_KICK = 29;
    public static final int BEFALL2 = 30;
    public static final int FATALITY = 31;
    public static final int BABALITY = 32;
    public static final int DIED = 33;
    //======================== frame sequence =================================
    public int[] idle;
    public int[] jump;
    public int[] run;
    public int[] forward;
    public int[] backward;
    public int[] sit;
    public int[] jumpBack;
    public int[] jumpFor;
    public int[] jumpFight;
    public int[] nearFight;
    //========
    public int[] punch;
    public int[] double_punch;
    public int[] down_punch;
    public int[] kick;
    public int[] kick_down;
    public int[] kick_up;
    public int[] kick_jump;
    public int[] wrestle;
    public int[] skill1;
    public int[] skill2;
    public int[] bePunch;
    public int[] beFall;
    public int[] beWrestle;
    public int[] highKick;
    public int[] fatality1;
    public int[] fatality2;
    public int[] fatality3;
    public int[] babality;
    //=========================  Hit  ====================
    public int[] hitPunch;
    public int[] hitDown_Punch;
    public int[] hitKick;
    public int[] hitKickDown;
//    public int[] hits;
    public int[] nearFightHit;
    public int[] hitHighKick;
    //========================= Other
    public int state = IDLE;
    public int count = -1;
    public int frameSet = 0;
    public boolean repeat = false;
    public int countRepeate = 0;
    public boolean left;
    public int testPunch = 0;
    public GameScreen gm;
    public Character rival;
    private int back;
    public boolean col = true;// for check in fight_ jump
    public boolean lui = true;
    public boolean use_gravity = true;
    public int resetGravity = 0;

    public Character(GameScreen gm, Character rival) {
        super(Asset.map1);
        this.rival = rival;
        backY = (gm.getHeight() > gm.map.getHeight()) ? (gm.getHeight() - 138) : (gm.map.getHeight() - 138);
//        this.defineReferencePixel(this.getWidth()/2, 0);
        this.gm = gm;
        this.autoControl = false;
        left = true;
//        Debug.d("Character");
    }
    // Put here to test

    public Character(int level, GameScreen gm) {
        super(Asset.map1);
//        this.rival = rival;
        backY = (gm.getHeight() > gm.map.getHeight()) ? (gm.getHeight() - 138) : (gm.map.getHeight() - 138);
//        this.defineReferencePixel(this.getWidth()/2, 0);
        this.gm = gm;
        this.autoControl = true;
        left = false;
    }

    public void setRival(Character rival) {
        this.rival = rival;
    }

    public void update() {
        if (use_gravity && this.state != SKILL1) {
            gravity();
        }
        switch (state) {
            case IDLE:
                this.idle();
                break;
            case BACKWARD:
                this.backWard();
                break;
            case FORWARD:
                this.forWard();
                break;
            case SIT:
                this.sit();
                break;
            case JUM:
                this.jump();
                break;
            case WRESTLE:
                wrestle();
                break;
            case JUMP_BACK:
                this.jump_back();
                break;
            case JUMP_FORWARD:
                this.jump_for();
                break;
            case KICK_DOWN:
                this.kickDown();
                break;
            case RUN:
                this.run();
                break;
            case KICK:
                this.kick();
                break;
            case PUNCH:
                this.punch();
                break;
            case PUNCH_DOWN:
                this.punch_down();
                break;
            case REPEATED_PUNCH:
                this.repeatedPunch();
                break;
            case JUMP_BACKWARD_FIGHT:
                this.jump_back_fight();
                break;
            case JUMP_FORWARD_FIGHT:
                this.jump_for_fight();
                break;
            case JUMP_FIGHT:
                this.jump_fight();
                break;
            case SKILL1:
                this.skill1();
                break;
            case SKILL2:
                this.skill2();
                break;
            case BEPUNCH:
                this.bePunch();
                break;
            case BEFALL1:
                this.beFall1();
                break;
            case BEFALL2:
                this.beFall2();
                break;
            case BEWRESTLE:
                this.beWrestle();
                break;
            case NEARFIGHT:
                this.nearly_fight();
                break;
            case HIGH_KICK:
                this.highKick();
                break;
            case BABALITY:
                babality();
                break;
            case FATALITY:
                fatality();
                break;
            case DIED:
                this.died();
                break;
            default:
                break;
        }
        if (collisionDetect() && gm.checkCollisionSpace) {
            Debug.d("Collision");
            if ((this.state == Character.RUN || this.state == Character.FORWARD) && rival.state == Character.IDLE) {
                // Han che van toc khi bi can
                if (this.state == Character.RUN) {
                    back = 9;
                } else {
                    back = 3;
                }
                // Neu o ben trai va neu o ben phai
                if (left) {
                    this.setPosition(this.getX() - back, rival.getY());
                    this.rival.setPosition(this.getX() + 48, rival.getY());
                } else {
                    this.setPosition(this.getX() + back, rival.getY());
                    this.rival.setPosition(this.getX() - 48, rival.getY());
                }
                // Neu ko phai bi han che khi can la bi. han che khi nhay
            } else if (this.getY() < this.backY) {
                if (left) {
                    this.setPosition(this.getX() - 3, this.getY());
                    rival.setPosition(rival.getX() + 3, rival.getY());
                } else {
                    this.setPosition(this.getX() + 3, this.getY());
                    rival.setPosition(rival.getX() - 3, rival.getY());
                }
            } else if (this.state == Character.IDLE && rival.state == Character.IDLE) {
                while (Math.abs(this.getPosX() - rival.getPosX()) < 48) {
                    if (left) {
                        Debug.d("1111111111111111");
                        this.setPosition(this.getX() - 2, this.getY());
                        rival.setPosition(rival.getX() + 2, rival.getY());
                    } else {
                        Debug.d("2222222222222222");
                        this.setPosition(this.getX() + 2, this.getY());
                        rival.setPosition(rival.getX() - 2, rival.getY());
                    }
                }
            }
        }

        updateRepeater();

    }

    public abstract void init();

    public abstract void present(Graphics g);

    public abstract void idle();

    public abstract void backWard();

    public abstract void forWard();

    public abstract void jump();

    public abstract void jump_back();

    public abstract void jump_for();

    public abstract void jump_fight();

    public abstract void jump_back_fight();

    public abstract void jump_for_fight();

    public abstract void sit();

    public abstract void run();

    // key 5 or fire key
    public abstract void punch();

    public abstract void punch_down();

    // repeat key 5 or fire key
    public abstract void repeatedPunch();

    // key forward and key kick
    public abstract void kick();

    // key sit and key kick
    public abstract void kickDown();

    public abstract void wrestle();

    public abstract void nearly_fight();

    public abstract void skill1();

    public abstract void skill2();

    public abstract void bePunch();

    public abstract void bePunch2();

    public abstract void beFall1();

    public abstract void beFall2();

    public abstract void beWrestle();

    public abstract void fatality();

    public abstract void babality();

    public abstract void highKick();

    public abstract void died();

    public void setVer(int dx, int dy) {
        this.dx = dx;
        this.dy = dy;
    }

    private void updateRepeater() {
        if (repeat) {
            if (++countRepeate > 7) {
                countRepeate = 0;
                repeat = false;
            }
        } else {
            countRepeate = 0;
        }

    }

    public void setImage(Image img, int frameWidth, int frameHeight) {
        super.setImage(img, frameWidth, frameHeight);
        if (!left) {
            this.setTransform(Sprite.TRANS_NONE);
            this.setTransform(Sprite.TRANS_MIRROR);
        } else {
            this.setTransform(Sprite.TRANS_NONE);
        }
    }

    public boolean collisionDetect() {
        if (this.collidesWith(rival, true) && (Math.abs(this.getX() - rival.getX()) < 48)) {
            return true;
        } else {
            return false;
        }
    }

    public int getPosX() {
        return this.getX() + this.getWidth() / 2;
    }

    public boolean inHit(int frame, int[] hit) {
        for (int i = 0; i < hit.length; i++) {
            if (frame == hit[i]) {
                return true;
            }
        }
        return false;
    }

    public void setState(int state) {
        this.state = state;
        this.count = -1;
    }

    public void gravity() {
        if (this.getY() < this.backY) {
            dy += 4;
        } else {
//            Debug.d("++++++++++++++++++++++++++++++++++++++++++++++==");
            this.setPosition(this.getX(), backY);
//            dy = 0;
        }
    }

    public void setCharacterCheckSpace(boolean b) {
        gm.checkCollisionSpace = b;
    }
}
